﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NewTicTacToe;
using System.Windows.Forms;
using ModelDll;
using NewTicTacToe.Properties;

namespace NewTicTacToe
{
    public class Controller
    {
                private Dictionary<PictureBox, sbyte> cellArrayDict = new Dictionary<PictureBox, sbyte>();
        public static bool gameCondition;

        public static Controller instanceController;
        public static TicTacToeForm instanceView;
        private Model instanceModel = new Model();
        private string nameWindow;

        static Controller()
        {
            instanceController = new Controller();
            instanceView = new TicTacToeForm();
            instanceController.cellArrayDict.Add(instanceView.picCell1, 0);
            instanceController.cellArrayDict.Add(instanceView.picCell2, 1);
            instanceController.cellArrayDict.Add(instanceView.picCell3, 2);
            instanceController.cellArrayDict.Add(instanceView.picCell4, 3);
            instanceController.cellArrayDict.Add(instanceView.picCell5, 4);
            instanceController.cellArrayDict.Add(instanceView.picCell6, 5);
            instanceController.cellArrayDict.Add(instanceView.picCell7, 6);
            instanceController.cellArrayDict.Add(instanceView.picCell8, 7);
            instanceController.cellArrayDict.Add(instanceView.picCell9, 8);
            instanceView.picCell10.Image = Resources.xPic;
            instanceController.instanceModel.GameTypeVar = Model.GameType.playerVsPlayer;
            instanceView.playerVsAIToolStripMenuItem.Checked = false;
            instanceView.playerVsPlayerToolStripMenuItem.Checked = true;
            instanceController.instanceModel.LevelAIvar = Model.LevelAi.hard;
            instanceView.hardToolStripMenuItem.Checked = true;
            instanceView.easyToolStripMenuItem.Checked = false;
            instanceController.nameWindow = instanceView.Text;
        }

        private Controller()
        {
        }

        private void AiMakeTurn(sbyte cellCounter)
        {
            this.instanceModel.cellArray[cellCounter] = Model.CellType.oCell;
            this.GetKeyByValue(cellCounter, this.cellArrayDict).Image = Resources.oPic;
            this.instanceModel.TurnType = true;
            this.TurnRateAi(cellCounter);
        }

        private void AiTurnEasy()
        {
            for (sbyte i = 0; i < ((sbyte) this.instanceModel.rowBest.Length); i = (sbyte) (i + 1))
            {
                if (this.instanceModel.cellArray[i] == Model.CellType.emptyCell)
                {
                    this.AiMakeTurn(i);
                    return;
                }
            }
            for (sbyte j = 0; j < this.instanceModel.cellArray.Length; j = (sbyte) (j + 1))
            {
                if (this.instanceModel.cellArray[j] == Model.CellType.emptyCell)
                {
                    this.AiMakeTurn(j);
                    return;
                }
            }
        }

        private void AiTurnHard()
        {
            for (int i = 0; i < this.instanceModel.rowArray.GetLength(0); i++)
            {
                if (this.instanceModel.rowArray[i, 0] <= -2)
                {
                    for (sbyte num2 = 1; num2 < ((sbyte) this.instanceModel.rowArray.GetLength(1)); num2 = (sbyte) (num2 + 1))
                    {
                        sbyte index = this.instanceModel.rowArray[i, num2];
                        if (this.instanceModel.cellArray[index] == Model.CellType.emptyCell)
                        {
                            this.AiMakeTurn(index);
                            return;
                        }
                    }
                }
            }
            for (int j = 0; j < this.instanceModel.rowArray.GetLength(0); j++)
            {
                if (this.instanceModel.rowArray[j, 0] >= 2)
                {
                    for (sbyte num5 = 1; num5 < ((sbyte) this.instanceModel.rowArray.GetLength(1)); num5 = (sbyte) (num5 + 1))
                    {
                        sbyte num6 = this.instanceModel.rowArray[j, num5];
                        if (this.instanceModel.cellArray[num6] == Model.CellType.emptyCell)
                        {
                            this.AiMakeTurn(num6);
                            return;
                        }
                    }
                }
            }
            for (int k = 0; k < this.instanceModel.rowArray.GetLength(0); k++)
            {
                if (this.instanceModel.rowArray[k, 0] <= -1)
                {
                    for (sbyte num8 = 1; num8 < ((sbyte) this.instanceModel.rowArray.GetLength(1)); num8 = (sbyte) (num8 + 1))
                    {
                        sbyte num9 = this.instanceModel.rowArray[k, num8];
                        if (this.instanceModel.cellArray[num9] == Model.CellType.emptyCell)
                        {
                            this.AiMakeTurn(num9);
                            return;
                        }
                    }
                }
            }
            for (sbyte m = 0; m < ((sbyte) this.instanceModel.rowBest.Length); m = (sbyte) (m + 1))
            {
                if (this.instanceModel.cellArray[this.instanceModel.rowBest[m]] == Model.CellType.emptyCell)
                {
                    this.AiMakeTurn(this.instanceModel.rowBest[m]);
                    return;
                }
            }
            for (sbyte n = 0; n < this.instanceModel.cellArray.Length; n = (sbyte) (n + 1))
            {
                if (this.instanceModel.cellArray[n] == Model.CellType.emptyCell)
                {
                    this.AiMakeTurn(n);
                    return;
                }
            }
        }

        private void ChangeCaptionInMainWin()
        {
            instanceView.Text = string.Concat(new object[] { this.nameWindow, " | X vs O (", this.instanceModel.XWinsCount, ":", this.instanceModel.OWinsCount, ")" });
        }

        private bool CheckWinner()
        {
            if ((this.instanceModel.TurnCount >= 5) && (this.instanceModel.TurnCount < 9))
            {
                if (((this.instanceModel.cellArray[0] == Model.CellType.xCell) && (this.instanceModel.cellArray[1] == Model.CellType.xCell)) && (this.instanceModel.cellArray[2] == Model.CellType.xCell))
                {
                    this.NameWinner(Model.CellType.xCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[3] == Model.CellType.xCell) && (this.instanceModel.cellArray[4] == Model.CellType.xCell)) && (this.instanceModel.cellArray[5] == Model.CellType.xCell))
                {
                    this.NameWinner(Model.CellType.xCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[6] == Model.CellType.xCell) && (this.instanceModel.cellArray[7] == Model.CellType.xCell)) && (this.instanceModel.cellArray[8] == Model.CellType.xCell))
                {
                    this.NameWinner(Model.CellType.xCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[0] == Model.CellType.xCell) && (this.instanceModel.cellArray[3] == Model.CellType.xCell)) && (this.instanceModel.cellArray[6] == Model.CellType.xCell))
                {
                    this.NameWinner(Model.CellType.xCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[1] == Model.CellType.xCell) && (this.instanceModel.cellArray[4] == Model.CellType.xCell)) && (this.instanceModel.cellArray[7] == Model.CellType.xCell))
                {
                    this.NameWinner(Model.CellType.xCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[2] == Model.CellType.xCell) && (this.instanceModel.cellArray[5] == Model.CellType.xCell)) && (this.instanceModel.cellArray[8] == Model.CellType.xCell))
                {
                    this.NameWinner(Model.CellType.xCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[0] == Model.CellType.xCell) && (this.instanceModel.cellArray[4] == Model.CellType.xCell)) && (this.instanceModel.cellArray[8] == Model.CellType.xCell))
                {
                    this.NameWinner(Model.CellType.xCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[6] == Model.CellType.xCell) && (this.instanceModel.cellArray[4] == Model.CellType.xCell)) && (this.instanceModel.cellArray[2] == Model.CellType.xCell))
                {
                    this.NameWinner(Model.CellType.xCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[0] == Model.CellType.oCell) && (this.instanceModel.cellArray[1] == Model.CellType.oCell)) && (this.instanceModel.cellArray[2] == Model.CellType.oCell))
                {
                    this.NameWinner(Model.CellType.oCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[3] == Model.CellType.oCell) && (this.instanceModel.cellArray[4] == Model.CellType.oCell)) && (this.instanceModel.cellArray[5] == Model.CellType.oCell))
                {
                    this.NameWinner(Model.CellType.oCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[6] == Model.CellType.oCell) && (this.instanceModel.cellArray[7] == Model.CellType.oCell)) && (this.instanceModel.cellArray[8] == Model.CellType.oCell))
                {
                    this.NameWinner(Model.CellType.oCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[0] == Model.CellType.oCell) && (this.instanceModel.cellArray[3] == Model.CellType.oCell)) && (this.instanceModel.cellArray[6] == Model.CellType.oCell))
                {
                    this.NameWinner(Model.CellType.oCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[1] == Model.CellType.oCell) && (this.instanceModel.cellArray[4] == Model.CellType.oCell)) && (this.instanceModel.cellArray[7] == Model.CellType.oCell))
                {
                    this.NameWinner(Model.CellType.oCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[2] == Model.CellType.oCell) && (this.instanceModel.cellArray[5] == Model.CellType.oCell)) && (this.instanceModel.cellArray[8] == Model.CellType.oCell))
                {
                    this.NameWinner(Model.CellType.oCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[0] == Model.CellType.oCell) && (this.instanceModel.cellArray[4] == Model.CellType.oCell)) && (this.instanceModel.cellArray[8] == Model.CellType.oCell))
                {
                    this.NameWinner(Model.CellType.oCell);
                    this.ChangeCaptionInMainWin();
                    return true;
                }
                if (((this.instanceModel.cellArray[6] == Model.CellType.oCell) && (this.instanceModel.cellArray[4] == Model.CellType.oCell)) && (this.instanceModel.cellArray[2] == Model.CellType.oCell))
                {
                    this.NameWinner(Model.CellType.oCell);
                }
            }
            else if (this.instanceModel.TurnCount == 9)
            {
                this.NameWinner(Model.CellType.emptyCell);
                return true;
            }
            return false;
        }

        private PictureBox GetKeyByValue(sbyte value, Dictionary<PictureBox, sbyte> dict)
        {
            foreach (KeyValuePair<PictureBox, sbyte> pair in dict)
            {
                if (pair.Value.Equals(value))
                {
                    return pair.Key;
                }
            }
            return null;
        }

        public void MakeTurn(PictureBox cellClicked)
        {
            if (gameCondition)
            {
                sbyte index = this.cellArrayDict[cellClicked];
                if (this.instanceModel.GameTypeVar == Model.GameType.playerVsPlayer)
                {
                    if (this.instanceModel.cellArray[index] == Model.CellType.emptyCell)
                    {
                        if (this.instanceModel.TurnType)
                        {
                            this.PlayerMakeTurn(cellClicked, index);
                            this.TurnRatePlayer(index);
                        }
                        else
                        {
                            cellClicked.Image = Resources.oPic;
                            this.instanceModel.TurnType = true;
                            this.instanceModel.cellArray[index] = Model.CellType.oCell;
                            this.TurnRateAi(index);
                        }
                        this.instanceModel.TurnCount = (byte) (this.instanceModel.TurnCount + 1);
                        this.WhoIsNextTurn();
                    }
                }
                else if ((this.instanceModel.GameTypeVar == Model.GameType.playerVsComputer) && (this.instanceModel.cellArray[index] == Model.CellType.emptyCell))
                {
                    this.PlayerMakeTurn(cellClicked, index);
                    this.TurnRatePlayer(index);
                    this.instanceModel.TurnCount = (byte) (this.instanceModel.TurnCount + 1);
                    this.WhoIsNextTurn();
                    if (this.CheckWinner())
                    {
                        return;
                    }
                    if (this.instanceModel.LevelAIvar == Model.LevelAi.easy)
                    {
                        this.AiTurnEasy();
                        this.instanceModel.TurnCount = (byte) (this.instanceModel.TurnCount + 1);
                        this.instanceModel.TurnType = false;
                    }
                    else if (this.instanceModel.LevelAIvar == Model.LevelAi.hard)
                    {
                        this.AiTurnHard();
                        this.instanceModel.TurnCount = (byte) (this.instanceModel.TurnCount + 1);
                        this.instanceModel.TurnType = false;
                    }
                }
                this.CheckWinner();
            }
        }

        public void MenuEvent(ToolStripMenuItem menuItem)
        {
            string text = menuItem.Text;
            if (text != null)
            {
                if (!(text == "Player vs Player"))
                {
                    if (!(text == "Player vs AI"))
                    {
                        if (!(text == "Easy"))
                        {
                            if (!(text == "Hard"))
                            {
                                if (text == "Exit")
                                {
                                    instanceView.Close();
                                }
                                return;
                            }
                            this.instanceModel.LevelAIvar = Model.LevelAi.hard;
                            menuItem.Checked = true;
                            instanceView.easyToolStripMenuItem.Checked = false;
                            return;
                        }
                        this.instanceModel.LevelAIvar = Model.LevelAi.easy;
                        menuItem.Checked = true;
                        instanceView.hardToolStripMenuItem.Checked = false;
                        return;
                    }
                }
                else
                {
                    this.instanceModel.GameTypeVar = Model.GameType.playerVsPlayer;
                    menuItem.Checked = true;
                    instanceView.playerVsAIToolStripMenuItem.Checked = false;
                    return;
                }
                this.instanceModel.GameTypeVar = Model.GameType.playerVsComputer;
                menuItem.Checked = true;
                instanceView.playerVsPlayerToolStripMenuItem.Checked = false;
            }
        }

        private void NameWinner(Model.CellType typeWinner)
        {
            if (typeWinner == Model.CellType.xCell)
            {
                MessageBox.Show("X Wins!");
                gameCondition = false;
                this.instanceModel.XWinsCount++;
            }
            else if (typeWinner == Model.CellType.oCell)
            {
                MessageBox.Show("0 Wins!");
                gameCondition = false;
                this.instanceModel.OWinsCount++;
            }
            else if (typeWinner == Model.CellType.emptyCell)
            {
                MessageBox.Show("Nobody Wins!");
                gameCondition = false;
            }
        }

        public void NewGame()
        {
            this.instanceModel.XWinsCount = 0;
            this.instanceModel.OWinsCount = 0;
            instanceView.Text = string.Concat(new object[] { this.nameWindow, " | X vs O (", this.instanceModel.XWinsCount, ":", this.instanceModel.OWinsCount, ")" });
            this.RestartGame();
        }

        private void PlayerMakeTurn(PictureBox cellClicked, sbyte curCellArray)
        {
            cellClicked.Image = Resources.xPic;
            this.instanceModel.TurnType = false;
            this.instanceModel.cellArray[curCellArray] = Model.CellType.xCell;
        }

        public void RestartGame()
        {
            this.instanceModel.TurnCount = 0;
            this.instanceModel.TurnType = true;
            for (sbyte i = 0; i < this.instanceModel.cellArray.Length; i = (sbyte) (i + 1))
            {
                this.instanceModel.cellArray[i] = Model.CellType.emptyCell;
                foreach (KeyValuePair<PictureBox, sbyte> pair in instanceController.cellArrayDict)
                {
                    pair.Key.Image = Resources.ePic;
                }
            }
            instanceView.picCell10.Image = Resources.xPic;
            this.instanceModel.ResetRate();
            gameCondition = true;
        }

        private void TurnRateAi(sbyte cellNumb)
        {
            switch (cellNumb)
            {
                case 0:
                    this.instanceModel.rowArray[0, 0]--;
                    this.instanceModel.rowArray[3, 0]--;
                    this.instanceModel.rowArray[6, 0]--;
                    break;
                case 1:
                    this.instanceModel.rowArray[0, 0]--;
                    this.instanceModel.rowArray[4, 0]--;
                    break;
                case 2:
                    this.instanceModel.rowArray[0, 0]--;
                    this.instanceModel.rowArray[5, 0]--;
                    this.instanceModel.rowArray[7, 0]--;
                    break;
                case 3:
                    this.instanceModel.rowArray[1, 0]--;
                    this.instanceModel.rowArray[3, 0]--;
                    break;
                case 4:
                    this.instanceModel.rowArray[1, 0]--;
                    this.instanceModel.rowArray[4, 0]--;
                    this.instanceModel.rowArray[6, 0]--;
                    this.instanceModel.rowArray[7, 0]--;
                    break;
                case 5:
                    this.instanceModel.rowArray[1, 0]--;
                    this.instanceModel.rowArray[5, 0]--;
                    break;
                case 6:
                    this.instanceModel.rowArray[2, 0]--;
                    this.instanceModel.rowArray[3, 0]--;
                    this.instanceModel.rowArray[7, 0]--;
                    break;
                case 7:
                    this.instanceModel.rowArray[2, 0]--;
                    this.instanceModel.rowArray[4, 0]--;
                    break;
                case 8:
                    this.instanceModel.rowArray[2, 0]--;
                    this.instanceModel.rowArray[5, 0]--;
                    this.instanceModel.rowArray[6, 0]--;
                    break;
            }
        }

        private void TurnRatePlayer(sbyte cellNumb)
        {
            switch (cellNumb)
            {
                case 0:
                    this.instanceModel.rowArray[0, 0]++;
                    this.instanceModel.rowArray[3, 0]++;
                    this.instanceModel.rowArray[6, 0]++;
                    break;
                case 1:
                    this.instanceModel.rowArray[0, 0]++;
                    this.instanceModel.rowArray[4, 0]++;
                    break;
                case 2:
                    this.instanceModel.rowArray[0, 0]++;
                    this.instanceModel.rowArray[5, 0]++;
                    this.instanceModel.rowArray[7, 0]++;
                    break;
                case 3:
                    this.instanceModel.rowArray[1, 0]++;
                    this.instanceModel.rowArray[3, 0]++;
                    break;
                case 4:
                    this.instanceModel.rowArray[1, 0]++;
                    this.instanceModel.rowArray[4, 0]++;
                    this.instanceModel.rowArray[6, 0]++;
                    this.instanceModel.rowArray[7, 0]++;
                    break;
                case 5:
                    this.instanceModel.rowArray[1, 0]++;
                    this.instanceModel.rowArray[5, 0]++;
                    break;
                case 6:
                    this.instanceModel.rowArray[2, 0]++;
                    this.instanceModel.rowArray[3, 0]++;
                    this.instanceModel.rowArray[7, 0]++;
                    break;
                case 7:
                    this.instanceModel.rowArray[2, 0]++;
                    this.instanceModel.rowArray[4, 0]++;
                    break;
                case 8:
                    this.instanceModel.rowArray[2, 0]++;
                    this.instanceModel.rowArray[5, 0]++;
                    this.instanceModel.rowArray[6, 0]++;
                    break;
            }
        }

        private void WhoIsNextTurn()
        {
            if ((this.instanceModel.TurnCount % 2) == 0)
            {
                instanceView.picCell10.Image = Resources.xPic;
            }
            else if ((this.instanceModel.TurnCount % 2) > 0)
            {
                instanceView.picCell10.Image = Resources.oPic;
            }
        }
    }
}
